import React, { Component } from 'react';
import { Modal, Toast } from 'antd-mobile';
import classnames from 'classnames';
import PubSub from 'pubsub-js';
import {
    getDeviceSn,
    getUuid,
    getDeviceOnline,
    sleep,
    playBaiduAudio,
    customPlayAudio,
    playControl,
    setMaxVolume,
    setPlayCircleType,
    setSleepTime,
    setLockMode,
    findCategoryAudioList
} from '../utils';
import {
    getCurrentAudio,
    existsAudioList,
    getCurrentAlbumList,
    handleDeviceOnine,
    handleCurrentPlayAudio,
    getBattery,
    getOnlineTitle,
    interceptOnline,
    interceptReceive,
    interceptEvent,
    notifyDeviceMode,
    findCategory
} from '../common/DeviceCtrolBiz';
import {
    COMMON_CATEGORY_ID,
    BAIDU_CATEGORY_ID,
    NEXT,
    PREVIOUS,
    PLAY_PAUSE,
    MQTT_ONLINE,
    MQTT_PALY_INFO,
    MQTT_LOCK,
    MQTT_PALY_PAUSE
} from '../config';
import NewPlayList from '../components/NewPlayList';
import MiniMediaPlay from '../components/MiniMediaPlay';
import Message from '../Message';
import AudioPlayOperate, { audio_operate } from '../components/AudioPlayOperate';
import '../css/nas.css';
import IconArrowDown from '../images/arrow_down.png';


// 设备本地或远程控制 
class DeviceControl extends Component {
    constructor(props, context) {
        super(props, context);
        this.executeCommand = this.executeCommand.bind(this);
        this.updateScreen = this.updateScreen.bind(this);
        this.handleReceiveMqttMessage = this.handleReceiveMqttMessage.bind(this);
        this.updateAlbumAudioList = this.updateAlbumAudioList.bind(this);
        // 存储用户出发的播放,暂停,以及上下首,点播
        this.queueList = [];
        this.state = {
            deviceId: this.props.deviceId,
            audio: null,
            album: null,
            isOnline: null,
            playStatus: '',
            playTime: 0,
            progress: 0,
            audioItemId: 0,
            volume: 100,
            circleType: 2,
            lock: 0,
            sleepTime: 0,
            battery: -1,
            version: '',
            category_id: COMMON_CATEGORY_ID,
            showList: false,
            showFullScreen: false,
            isDeploy: false
        };
    }

    componentWillReceiveProps(nextProps) {
        if (this.state.deviceId !== nextProps.deviceId) {
            this.setState({ deviceId: nextProps.deviceId });
            this.initMQTT();
        }
        if (nextProps.isDeploy !== this.state.isDeploy) {
            this.setState({
                isDeploy: nextProps.isDeploy
            });
            if (nextProps.isDeploy && this.state.playStatus !== 'paused') {
                if (!this.state.audio) {
                    // 延迟一定时长后再更新设备在线状态
                    this.delayUpdateState();
                    // 轮询获取设备在线状态信息
                    this.polingCheckDevice();
                } else {
                    this.canUpdate = true;
                }
            }
        }
    }

    componentDidMount() {
        // 启动进度任务
        this.intervalProgress();
        // 监听点播
        this.pubSubPlay = PubSub.subscribe('remotePlay', (topic, message) => {
            // 进度暂停
            this.canUpdate = false;
            const { category_id, audio, audioList } = message;
            Toast.success('开始播放' + audio.name, 1, false);
            this.playAudio(audio, audioList, category_id);
        })
        // 监听操作设备事件
        this.pubSubContrl = PubSub.subscribe('contrlDevice', (topic, message) => {
            if (message.type === undefined) {
                if (this.state.showFullScreen) {
                    this.setState({ showFullScreen: false });
                }
            }else if(message.type === audio_operate.upgrade_online) {
                this.setState({
                    isDeploy:true
                });
                console.log(`message.type :${message.type },${this.state.isOnline}`);
                if (!this.state.isOnline) {
                    this.polingCheckDevice();
                }
            }else if (message.type === audio_operate.force_offline) {
                this.setState({ isOnline: false });
            } else {
                this.executeCommand(message);
            }
        });
    }

    componentWillUnmount() {
        if (this.mqttMessage) {
            this.mqttMessage.disconnect();
        }
        PubSub.unsubscribe(this.pubSubPlay);
        PubSub.unsubscribe(this.pubSubContrl);
        clearInterval(this.progressInterval);
    }

    async polingCheckDevice() {
        for (let index = 0; index < 2; index++) {
            const uuid = getUuid();
            if (uuid) {
                const result = await getDeviceOnline(uuid);
                console.log(`result:`,result);
                this.decodeDeviceOnline(result);
            }
            await sleep(4000);
            if (this.state.isOnline) {
                break;
            }
        }
    }

    // mqtt 仅接收来自服务器推送消息
    initMQTT() {
        const device_sn = getDeviceSn();
        if (device_sn && !this.mqttMessage) {
            this.mqttMessage = new Message(device_sn, this.handleReceiveMqttMessage);
        }
    }

    // 接收MQTT消息,目前仅仅是接收设备信息
    async handleReceiveMqttMessage(topic, message) {
        if (!this.state.isDeploy && !this.state.audio) {
            console.log(`未展开,减少http请求`);
            return;
        }
        try {
            const json = JSON.parse(message);
            this.dispatchEvent(json);
        } catch (error) {
            console.error(error);
        }
    }
    // 正常模式
    isNormalMode() {
        return this.state.category_id === COMMON_CATEGORY_ID || this.state.category_id === BAIDU_CATEGORY_ID;
    }

    // 分发类型事件
    dispatchEvent(json) {
        switch (json.type) {
            case MQTT_ONLINE:
                if (interceptOnline()) {
                    getDeviceOnline(getUuid()).then((data) => {
                        this.decodeDeviceOnline(data);
                    })
                }
                break;
            case MQTT_PALY_INFO:
                if (this.queueList.length === 0 && !interceptReceive()) {
                    handleDeviceOnine(this.state.audio, this.state.album, (ret) => {
                        if (ret.exists) {
                            let audio = ret.audio;
                            if (!this.isNormalMode()) {
                                console.log(`播放列表模式:${this.state.category_id}`);
                                audio = Object.assign(audio, { store_category_id: this.state.category_id });
                            }
                            this.setState({
                                audio: audio
                            });
                            this.canUpdate = true;
                            this.updateProgress(parseInt(ret.playTime || 0, 10));
                            sessionStorage.setItem('online', 1)
                        } else {
                            this.decodeDeviceOnline(ret.data);
                        }
                    });
                }
                break;
            case MQTT_LOCK:
                this.setState({ lock: json.value });
                break;
            case MQTT_PALY_PAUSE:
                if (json.value === 0) {
                    this.canUpdate = false;
                    this.setState({ playStatus: 'paused' });
                } else {
                    this.canUpdate = true;
                    this.setState({ playStatus: 'playing' });
                }
                break;
            default:
                console.log(`unknown:${json.type}`);
                break;
        }
    }

    // 解析设备上线数据
    async decodeDeviceOnline(data) {
        const isOnline = Number(data.code) === 0;
        if (!isOnline) {
            if (this.state.isOnline) {
                this.canUpdate = false;
                this.setState({ isOnline: false, progress: 0, audio: null, album: null });
                // 更新本地数据以及发送通知
                sessionStorage.setItem('online', 0)
            }
            return;
        }
        sessionStorage.setItem('online', 1);
        // 获取设备返回的数据
        const { play_time, audioItemId, circle_type, is_lock, volume, battery, version, favorite_category } = JSON.parse(data.data.content).data;
        localStorage.setItem('ota_version', version);
        const categoryId = favorite_category ? favorite_category : COMMON_CATEGORY_ID;
        this.setState({
            isOnline: true,
            category_id: categoryId,
            playTime: play_time,
            audioItemId: audioItemId,
            circleType: circle_type,
            lock: is_lock,
            volume: volume,
            battery: battery,
            version: version
        });
        // 更新本地数据以及发送通知
        if (!audioItemId) {
            this.canUpdate = false;
            this.setState({ playStatus: '' });
            return;
        }
        // 获取当前播放的音频信息，以及播放列表
        const playTime = parseInt(play_time, 10);
        const { audio } = await getCurrentAudio(parseInt(audioItemId, 10), playTime);
        if (this.isNormalMode()) {
            this.setState({
                audio: audio
            });
        } else {
            this.setState({
                audio: Object.assign(audio, { store_category_id: categoryId, album_id: categoryId })
            });
        }
        this.canUpdate = true;
        this.updateProgress(playTime);
        this.getCurrent(audio, categoryId);
    }

    async getCurrent(audio, categoryId) {
        if (this.isNormalMode()) {
            const upid = existsAudioList(audio, this.state.album);
            const { album } = await getCurrentAlbumList(audio, upid);
            if (album) {
                this.setState({
                    album: album
                });
            }
        } else {
            const data = await findCategoryAudioList(categoryId);
            if (data && data.errcode === 0) {
                let audioList = data.data;
                audioList = audioList.map((item) => {
                    return Object.assign(item, { album_id: categoryId, store_category_id: categoryId });
                });
                if (audioList.length) {
                    const category = findCategory(categoryId);
                    const album = {
                        album_id: categoryId,
                        album_url: category.url,
                        name: audioList[0].album_name,
                        list: audioList
                    };
                    this.setState({
                        album: album
                    });
                }
            }

        }
    }
    // 延迟展示在线状态
    async delayUpdateState() {
        await sleep(5000);
        if (this.state.isOnline === null) {
            this.setState({ isOnline: false });
            sessionStorage.setItem('online', 0);
        }
    }

    // 播放状态下，定时更新进度
    intervalProgress() {
        this.progressInterval = setInterval(() => {
            if (this.canUpdate && this.state.audio && this.state.progress < 100) {
                const duration = this.state.audio.duration;
                if (duration) {
                    let progress = this.state.progress + Math.floor(100 / duration * 100) / 100;
                    if (progress > 100) {
                        progress = 100;
                    }
                    this.setState({
                        playStatus: 'playing',
                        progress: Math.floor(progress * 100) / 100
                    });
                }
            };
        }, 1000);
    }

    // 更新播放进度
    updateProgress(playTime) {
        const playTimeSecond = Number(playTime / 1000);
        const progress = Math.floor(playTimeSecond / this.state.audio.duration * 100 * 100) / 100;
        if (progress > 100) {
            return;
        }
        this.setState({ progress: progress, playStatus: 'playing' });
    }

    // 对用户触发的操作百度接口进行mqtt消息拦截
    addActionTask() {
        this.queueList.push(0);
    }

    /**
     * 播放音频
     * @param {*} audio 
     * @param {*} audioList 
     * @param {*} category_id 
     */
    playAudio(audio, audioList, category_id) {
        console.log(`uuid:${getUuid()}, album_id:${audio.album_id}, audio_id:${audio.audio_id}, audioListCount:${audioList.length}`);
        this.addActionTask();
        //  通用类别:,没有类别
        if (category_id === COMMON_CATEGORY_ID || category_id === BAIDU_CATEGORY_ID) {
            playBaiduAudio(getUuid(), audio.album_id, audio.audio_id, (result) => {
                setTimeout(() => {
                    this.queueList.pop();
                }, 3000);
                const code = parseInt(result.errcode, 10);
                if (code === 0) {
                    this.canUpdate = true;
                    this.setState({ progress: 0, audio: audio, playStatus: 'playing', isOnline: true, category_id: category_id });
                    sessionStorage.setItem('online', 1);

                    // 目前点播都可以调动下
                    notifyDeviceMode(audio.audio_id, -1);
                    // 如果当前已经这个专辑
                    if (this.state.album && this.state.album.list.length > 0) {
                        if (this.state.album.list[0].album_id === audio.album_id) {
                            if (this.state.album.list.length === audioList.length) {
                                console.log(`播放拦截,已存在相同的播放列表`);
                                return;
                            }
                        }
                    }
                    // 没有播放列表才获取,只有搜索音频点播才会执行
                    if (audioList.length === 0) {
                        this.getCurrent(audio, this.state.category_id);
                    } else {
                        const newAlbum = {
                            album_id: audio.album_id,
                            album_url: audioList[0].img_url,
                            name: audioList[0].album_name,
                            list: audioList
                        };
                        this.setState({ album: newAlbum });
                    }
                } else if (code === 1338) {
                    this.canUpdate = false;
                    this.setState({
                        isOnline: false,
                    });
                    Toast.offline('设备已离线', 1, false);
                } else {
                    this.canUpdate = false;
                    Toast.offline('播放失败', 1, false);
                }
            });
        } else {
            this.playStoreCategory(audio, audioList, category_id);
        }
    }


    /**
     * 点播收藏音频
     * @param {点播音频} audio 
     * @param {播放列表} audioList 
     * @param {播放类别} category_id 
     */
    async playStoreCategory(audio, audioList = [], category_id) {
        const curIndex = audioList.findIndex((item) => {
            return audio.audio_id === item.audio_id;
        });
        let beforeAudioId = 0;
        if (curIndex > 0) {
            beforeAudioId = audioList[curIndex - 1].audio_id;
        }
        console.log(`通知设备播放的上一次位置:${beforeAudioId}`);
        const result = await customPlayAudio(category_id, beforeAudioId);
        console.log(JSON.stringify(result));
        setTimeout(() => {
            this.queueList.pop();
        }, 5000);
        // 自定义播放音频失败
        if (result.errcode !== 0) {
            this.canUpdate = false;
            if (result.errcode === 1338) {
                this.setState({
                    isOnline: false,
                });
                Toast.offline('设备已离线', 1, false);
            } else {
                Toast.fail('播放失败', 1, false);
            }
            return;
        }
        this.canUpdate = true;
        // 类别id就是专辑id
        const category = findCategory(audio.store_category_id);
        const newAlbum = {
            album_id: audio.store_category_id,
            album_url: category.url,
            name: audioList[0].name,
            list: audioList
        };
        this.setState({
            category_id: category_id,
            progress: 0,
            audio: audio,
            playStatus: 'playing',
            isOnline: true,
            album: newAlbum
        });
        notifyDeviceMode(audio.audio_id, category_id);
    }

    showPlayList(show) {
        this.setState({ showList: show });
    }

    playAudioList = (audio) => {
        this.setState({ showList: false });
        this.playAudio(audio, this.state.album.list, this.state.category_id);
    }

    updateScreen(show) {
        this.setState({ showFullScreen: show });
    }

    executeCommand(command) {
        switch (command.type) {
            case audio_operate.previous: // 上一首
                this.contrlDeviceAction(PREVIOUS);
                break;
            case audio_operate.play_pause: // 暂停或播放
                if (this.state.audio) {
                    this.contrlDeviceAction(PLAY_PAUSE);
                } else {
                    Toast.show('未点播音频', 1, false);
                }
                break;
            case audio_operate.play_list:
                this.setState({ showList: true });
                break;
            case audio_operate.next: // 下一首
                this.contrlDeviceAction(NEXT);
                break;
            case audio_operate.volume:
                setMaxVolume(getUuid(), command.value, (data) => {
                    if (data.code && parseInt(data.code, 10) === 0) {
                        this.setState({
                            volume: command.value
                        });
                        Toast.success('设置音量成功', 1, false);
                    } else {
                        Toast.offline('设置音量失败', 1, false);
                    }
                })
                break;
            case audio_operate.lock:
                setLockMode(getUuid(), command.value, (data) => {
                    if (data.code && parseInt(data.code, 10) === 0) {
                        this.setState({ lock: command.value });
                        Toast.success('设置童锁成功', 1, false);
                    } else {
                        Toast.offline('设置童锁失败', 1, false);
                    }
                })
                break;
            case audio_operate.sleep_time:
                setSleepTime(getUuid(), command.value, (data) => {
                    if (data.code && parseInt(data.code, 10) === 0) {
                        this.setState({
                            sleepTime: command.value
                        });
                        Toast.success('设置休眠时间成功', 1, false);
                    } else {
                        Toast.offline('设置休眠时间失败', 1, false);
                    }
                })
                break;
            case audio_operate.circle:
                setPlayCircleType(getUuid(), command.value, (data) => {
                    if (data.code && parseInt(data.code, 10) === 0) {
                        this.setState({
                            circleType: command.value
                        });
                        Toast.success('设置播放模式成功', 1, false);
                    } else {
                        Toast.offline('设置播放模式失败', 1, false);
                    }
                })
                break;
            default:
                console.log("unknown");
                break;
        }
    }

    // 暂停/播 以及上下首
    async contrlDeviceAction(action) {
        if (interceptEvent()) {
            return;
        }
        this.addActionTask();
        const isNormal = this.isNormalMode();
        if (isNormal || (!isNormal && action ===PLAY_PAUSE)) {
            playControl(getUuid(), action, (result) => {
                setTimeout(() => {
                    this.queueList.pop();
                }, isNormal ? 3000 : 5000);
                if (this.isSuccessCode(parseInt(result.errcode, 10))) {
                    this.handleActionSuccess(action);
                }
            });
        } else {
            this.playStorePrevious(this.state.album, this.state.audio, this.state.category_id, action);
        }
    }

    // 播放上一首
    async playStorePrevious(album, audio, categoryId, action) {
        const audioList = album.list;
        const lastestIndex = audioList.findIndex((item) => {
            return audio.audio_id === item.audio_id;
        });
        // 即将播放的音频
        let currentAudio = null;
        let beforeAudioId = 0;

        if (action === NEXT) {
            // 当前已经是最后一首
            if (lastestIndex !== audioList.length - 1) {
                beforeAudioId = audio.audio_id;
            }
            if (beforeAudioId > 0) {
                currentAudio = audioList[lastestIndex + 1];
            }else {
                currentAudio = audioList[0];
            }

        } else {
            // 播放上一首音频，记录的位置需要加上2
            if (lastestIndex >= 2) {
                beforeAudioId = audioList[lastestIndex - 2].audio_id;
            }
            // 播放位置最起码距离第一首还有两首
            if (beforeAudioId > 0) {
                currentAudio = audioList[lastestIndex - 1];
            } else {
                currentAudio = audioList[0];
            }
        }

        const result = await customPlayAudio(categoryId, beforeAudioId);
        setTimeout(() => {
            this.queueList.pop();
        }, 5000);
        if (result.errcode !== 0) {
            this.canUpdate = false;
            if (result.errcode === 1338) {
                this.setState({
                    isOnline: false,
                });
                Toast.offline('设备已离线', 1, false);
            } else {
                Toast.fail('播放失败', 1, false);
            }
            return;
        }
        this.canUpdate = true;
        this.setState({ progress: 0, audio: currentAudio, playStatus: 'playing', isOnline: true });
    }


    // 显示对应的提示信息
    isSuccessCode(errCode) {
        if (errCode === 0) {
            return true;
        }
        if (errCode === 2306) {
            Toast.show('已经是第一首了', 2, false);
        } else if (errCode === 2305) {
            Toast.show('已经是最后一首了', 2, false);
        } else if (errCode === 1005) {
            console.log('签名问题,操作设备可以接收到指令');
            return true;
        } else {
            Toast.offline('操作失败', 2, false);
        }
        return false;
    }

    // 处理点播,上下首操作成功
    handleActionSuccess(action) {
        if (action === PLAY_PAUSE) {
            if (this.state.playStatus === 'playing') {
                this.canUpdate = false
                this.setState({ playStatus: 'paused' });
            } else {
                this.canUpdate = true
                this.setState({ playStatus: 'playing' });
            }
            return;
        }
        if (this.state.audio && this.state.album && this.state.album.list.length) {
            handleCurrentPlayAudio(this.state.category_id, this.state.album, this.state.audio, action, (ret) => {
                if (ret.audio) {
                    this.canUpdate = true;
                    this.setState({ progress: 0, audio: ret.audio, playStatus: 'playing', isOnline: true });
                    if (ret.audioList) {
                        let list = this.state.album.list;
                        list = list.concat(ret.audioList)
                        const album = Object.assign(this.state.album, { list: list });
                        this.setState({
                            album: album
                        });
                    }
                }
            });
        }
    }

    // 更新专辑中的音频数据
    updateAlbumAudioList(audioList) {
        const album = Object.assign(this.state.album, { list: audioList });
        this.setState({
            album: album
        });
    }

    render() {
        let albumCover = this.state.album ? this.state.album.album_url : 'http://resource.alilo.com.cn/res/5,013392a61b7f67';
        return (
            <div id='contrl'>
                <Modal popup visible={this.state.showFullScreen} animationType="slide-down">
                    <div className="container-full">
                        <div style={{ width: '100%', height: '100%', position: 'absolute' }}>
                            <div className="container-bg" style={{ backgroundImage: `url(http://resource.alilo.com.cn/res/5,013392a61b7f67)` }} />
                            <div className="play_contrl_head">
                                <div style={styles.second_div}>
                                    <div style={styles.left_right_div}>
                                        <img src={IconArrowDown} style={{ width: 28, height: 28 }} onClick={this.updateScreen.bind(this, false)} alt='' />
                                    </div>
                                    <div style={styles.middle_div}>
                                        <div style={{ height: "70%", display: "flex", justifyContent: "center", alignItems: "center" }}>
                                            <span style={styles.state_caption}>{getOnlineTitle(this.state.isOnline, this.state.audio)}</span>
                                        </div>
                                        <div style={{ height: "30%", display: "flex", justifyContent: "center", alignItems: "center" }}>
                                            <span style={styles.battery_caption}>{getBattery(this.state.isOnline, this.state.battery)}</span>
                                        </div>
                                    </div>
                                    <div style={styles.left_right_div} />
                                </div>
                            </div>
                            <div className="album_container">
                                <div className="components-album">
                                    <div
                                        className={classnames('components-album-album-pic', this.state.playStatus === 'playing' ? 'components-album-palying' : 'components-album-paused')}
                                        style={{ background: `url(${albumCover}) center center`, backgroundSize: 'cover' }} />
                                </div>
                            </div>

                            <div style={styles.full}>
                                <AudioPlayOperate
                                    album={this.state.album}
                                    audio={this.state.audio}
                                    isPlaying={this.state.playStatus === 'playing'}
                                    progress={this.state.progress}
                                    circleType={this.state.circleType}
                                    sleepTime={this.state.sleepTime}
                                    lock={this.state.lock}
                                    volume={this.state.volume}
                                    showList={this.showPlayList.bind(this, true)}
                                    executeCommand={this.executeCommand} />
                            </div>
                        </div>
                    </div>
                </Modal>
                <div style={styles.mini}>
                    <MiniMediaPlay
                        stateText={getOnlineTitle(this.state.isOnline, this.state.audio)}
                        progress={this.state.progress}
                        isOnline={this.state.isOnline}
                        isPlaying={this.state.playStatus === 'playing'}
                        fullScreen={this.updateScreen.bind(this, true)}
                        albumCoverUrl={this.state.album ? this.state.album.album_url : ''}
                        executeCommand={this.executeCommand} />
                </div>
                <Modal
                    popup
                    onClose={this.showPlayList.bind(this, false)}
                    visible={this.state.showList}
                    animationType="slide-up">
                    <div style={{ height: '60vh', overflow: 'hidden' }}>
                        <NewPlayList
                            album={this.state.album}
                            audio={this.state.audio}
                            isPlaying={this.state.playStatus === 'playing'}
                            playAudioList={this.playAudioList}
                            hidden={this.showPlayList.bind(this, false)}
                            category_id={this.state.category_id}
                            updateAlbumAudioList={this.updateAlbumAudioList} />
                    </div>
                </Modal>
            </div>
        );
    }
};

export default DeviceControl;

const styles = {
    mini: {
        bottom: 0,
        width: '100%'
    },
    full: {
        width: '100%',
        height: '180px',
        position: 'fixed',
        bottom: 0,
        zIndex: 102
    },
    second_div: {
        display: "flex",
        width: '100%',
        height: '46px'
    },
    left_right_div: {
        width: "15%",
        display: "flex",
        alignItems: "center",
        justifyContent: 'center'
    },

    middle_div: {
        width: "70%",
        height: '46px'
    },
    state_caption: {
        fontSize: '15px',
        textAlign: 'center',
        color: 'black',
        overflow: 'hidden',
        textOverflow: 'ellipsis',
        whiteSpace: 'nowrap'
    },
    battery_caption: {
        fontSize: '12px',
        textAlign: 'center',
        color: '#757575',
        overflow: 'hidden',
        textOverflow: 'ellipsis',
        whiteSpace: 'nowrap'
    }
}
